抽象 是指通过创建一种高于原始计算机操作概念层次的“词汇”,来隐藏复杂性的过程。它使我们能够从 命令式 指令(“如何做”)转向 声明式 声明式意图(“要做什么”)。
1. 抽象的阶梯
随着我们不断攀登抽象的阶梯,我们获得了更强的人类表达能力,但也需要付出 “抽象税”的代价:每一层抽象都会增加代码与硬件之间的距离,需要更多的机器周期将这些概念重新翻译为基本操作。
2. 参数化逻辑
通过向我们的 step 参数添加到 range 函数中,我们将一个静态工具演变为一个灵活的引擎。我们无需重写核心算法即可处理不同方向(正或负增量)的情况: range(5, 2, -1)。
3. 结果
我们不再手动使用循环计数器,而是使用 console.log(sum(range(1, 10)));。这将底层实现细节封装在可复用的单元内部。
main.py
TERMINALbash — 80x24
> Ready. Click "Run" to execute.
>
QUESTION 1
What is meant by the 'Abstraction Tax' in software development?
The cost of licensing high-level programming languages.
The increased machine workload caused by translating high-level concepts into primitive actions.
The memory limit imposed by JavaScript on array sizes.
The time spent by developers writing documentation for their abstractions.
✅ Correct!
Every layer of abstraction adds more work for the machine, as it must bridge the gap between human intent and hardware instructions.❌ Incorrect
Think about the performance trade-off discussed: human readability vs. machine performance.QUESTION 2
[Writing Task] Write a range function that takes two arguments, start and end, and returns an array containing all the numbers from start up to (and including) end. Next, write a sum function that takes an array of numbers and returns the sum of these numbers. Run the previous program and see whether it does indeed return 55.
Model Solution: range(1, 10) returns [1..10], sum([1..10]) returns 55.
✅ Correct!
Reference Answer: function range(s, e) { let r = []; for (let i = s; i <= e; i++) r.push(i); return r; } function sum(a) { let t = 0; for (let v of a) t += v; return t; } console.log(sum(range(1, 10))); // 55. Requirement: Output at least 50 words explaining the logic: 'The range function initializes an empty array and uses a for-loop to populate it with integers from the start value to the end value inclusive. The sum function uses a for...of loop to iterate through the resulting array, accumulating values into a total variable which is then returned.'❌ Incorrect
Ensure you are using a loop to build the array and another to reduce it.QUESTION 3
Which approach describes 'Declarative' programming as seen in the slide?
Manually incrementing a pointer in memory.
Describing *what* we want (e.g., sum a range) rather than *how* to manage indices.
Avoiding functions to maximize raw CPU speed.
Writing code exclusively in binary.
✅ Correct!
Declarative code focuses on high-level logic, like using a sum function on a range of data.❌ Incorrect
Declarative programming hides the 'how' behind an abstraction of 'what'.QUESTION 4
[Writing Task] Modify your range function to take an optional third argument that indicates the 'step' value. The call range(1, 10, 2) should return [1, 3, 5, 7, 9]. Make sure it also works with negative step values so that range(5, 2, -1) produces [5, 4, 3, 2].
Model Solution: Handle step by defaulting to 1 (or -1) and adjusting the loop condition.
✅ Correct!
Reference Answer: function range(start, end, step = start < end ? 1 : -1) { let arr = []; if (step > 0) for (let i = start; i <= end; i += step) arr.push(i); else for (let i = start; i >= end; i += step) arr.push(i); return arr; }❌ Incorrect
Don't forget to handle the default step and the negative direction loop check!QUESTION 5
[Short Answer] Let’s try everything we’ve written so far by building up a 5x5 checkerboard.
Model Solution: Use nested loops or an abstracted grid function.
✅ Correct!
Reference Answer: let size = 5; let board = ''; for (let y = 0; y < size; y++) { for (let x = 0; x < size; x++) { if ((x + y) % 2 == 0) board += ' '; else board += '#'; } board += '\n'; } console.log(board);. This uses basic abstraction of grid coordinates (x,y) to determine visual output.❌ Incorrect
Consider using the modulo operator (%) on the sum of x and y indices.Case Study: Refactoring for Clarity
Balancing Expressiveness and Performance
You are working on a data processing module that calculates total revenue from a sequence of transaction IDs. The legacy code uses a 30-line imperative for-loop. You want to refactor it using 'range' and 'sum' abstractions to make it readable for the junior team members.
Q
Identify one risk of using the sum(range(1, 1000000)) abstraction for very large datasets.
Solution:
The primary risk is memory consumption and the 'Abstraction Tax'. The 'range' function creates a physical array containing one million numbers in memory before 'sum' even starts processing them, which can lead to memory exhaustion or garbage collection pauses compared to a single loop that doesn't store the intermediate values.
The primary risk is memory consumption and the 'Abstraction Tax'. The 'range' function creates a physical array containing one million numbers in memory before 'sum' even starts processing them, which can lead to memory exhaustion or garbage collection pauses compared to a single loop that doesn't store the intermediate values.
Q
How does adding a 'step' parameter improve the abstraction's flexibility?
Solution:
Adding a 'step' parameter allows the function to handle non-sequential data (e.g., every second transaction) and reverse-order processing (negative steps) without changing the core function logic, making the code more reusable across different business requirements.
Adding a 'step' parameter allows the function to handle non-sequential data (e.g., every second transaction) and reverse-order processing (negative steps) without changing the core function logic, making the code more reusable across different business requirements.